{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[this doc on github](https://github.com/dotnet/interactive/tree/main/samples/notebooks/powershell)\n",
    "\n",
    "# Using For-EachObject -Parallel in PowerShell 7 <img src=\"https://raw.githubusercontent.com/PowerShell/PowerShell/master/assets/Powershell_black_64.png\" align=\"right\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you are a PowerShell user you are likely already familiar with the For-EachObject command.\n",
    "In the past you have used it with the -Proccess parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "1..5 | ForEach-Object -Process {write-output \"This is number $_\"; sleep 1}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "(Measure-Command { \n",
    "    1..5 | ForEach-Object -Process {write-output \"This is number $_\"; sleep 1}\n",
    "    }).Seconds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, with the introduction of the -Parallel paramter in PowerShell 7 we can improve the performance of this command."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "(Measure-Command { \n",
    "    1..5 | ForEach-Object -Parallel {write-output \"This is number $_\"; sleep 1}\n",
    "    }).Seconds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While this may seem trivial in the example above, you can begin applying this to larger tasks. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "function FetchGitHubRepos {\n",
    "    $orgs = @(\n",
    "        'PowerShell',\n",
    "        'Microsoft',\n",
    "        'dotnet'\n",
    "    )\n",
    "\n",
    "    Measure-Command -Expression {\n",
    "        foreach($org in $orgs) {\n",
    "            1..10 | ForEach-Object -ThrottleLimit 3 -Parallel {\n",
    "                (Invoke-RestMethod \"https://api.github.com/orgs/$using:org/repos?page=$_\") |\n",
    "                Select-Object -Property full_name,stargazers_count |\n",
    "                Export-Csv ./repo_stats.csv -Append\n",
    "            }\n",
    "        }\n",
    "    } | Select-Object -Property Minutes, Seconds\n",
    "}\n",
    "FetchGitHubRepos"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you'd like to see the result of that cell, just run this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "Get-Content repo_stats.csv |\n",
    "    ConvertFrom-Csv |\n",
    "    Sort-Object { $_.stargazers_count -as [int] } -Descending |\n",
    "    Select-Object -First 20"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (PowerShell)",
   "language": "PowerShell",
   "name": ".net-powershell"
  },
  "language_info": {
   "file_extension": ".ps1",
   "mimetype": "text/x-powershell",
   "name": "PowerShell",
   "pygments_lexer": "powershell",
   "version": "7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}